import java.util.LinkedList;


public class Board {

	private Place[] places= new Place[121]; 
	LinkedList<Player> players = new LinkedList<Player>();
	public Player player;//turn
	int countTurn=0;
	int width=800;
	int heigth=600;
	int stoneSize=35;
	int selectedStone=-1;

	/***
	 * 
	 * @param i the number of the place
	 * @return a Place at this number :
	 * @see <a href="Place.html">Place classe</a>
	 * <br>Take a look at relative position of places:<br>
	 * <img src="resources/position.jpg" alt="Places number" />
	 */
	public Place getPlace(int i){
		return places[i];
	}

	/***
	 * 
	 * @param Player p initiate the free place number
	 * <br>On this picture: Player 0 and 3<br> 
	 * <img src="resources/free.jpg" alt="free places on the board" />
	 */
	void loadfreeplace(Player p){

		for(int i=0;i<10;i++){
			places[p.getStoneAbs(i)].free=p.position;
		}

	}

	private void pathBoard(int nb,int lenght,int x,int y, int dx, int dy,int etape,int bx,int by){

		for (int i=0;i<lenght;i++){
			places[nb+i]= new Place(nb+i,x+=dx,y+=dy,etape,bx,by);
			if(places[nb+i].branche==1||places[nb+i].branche==8||places[nb+i].branche==10||places[nb+i].branche==11){
				places[nb+i].bx++;
				bx++;
			}else if(places[nb+i].branche==2||places[nb+i].branche==4||places[nb+i].branche==5||places[nb+i].branche==7){
				places[nb+i].bx--;
				bx--;
			}

			if(places[nb+i].branche==0||places[nb+i].branche==1||places[nb+i].branche==3||places[nb+i].branche==10){
				places[nb+i].by++;
				by++;
			}else if(places[nb+i].branche==4||places[nb+i].branche==6||places[nb+i].branche==7||places[nb+i].branche==9){
				places[nb+i].by--;
				by--;
			}


		}
		pathBoard(nb+lenght, x, y,etape+1,bx,by);
	}

	private void pathBoard(int nb,int x, int y,int etape,int bx,int  by){
		if (nb==places.length)return;
		etape=etape%12;


		int len;
		if(nb>109)len=1;
		else if(nb>86)len=2;
		else if(nb>51)len=3;
		else if(nb>1)len=4;
		else len=5;


		if((etape==0)||(etape==3)){        //d3
			if (nb==0){
				pathBoard(nb,len,x,y,stoneSize/2,stoneSize,etape,bx,by);	
			}else{
				pathBoard(nb,len,x,y,stoneSize/2,stoneSize,etape,bx,by);
			}
		}else if (etape==1 ||etape==10){             //d2
			pathBoard(nb,len,x,y,stoneSize,0,etape,bx,by);	
		}else if((etape==2)||(etape==5)) {                     //g3
			pathBoard(nb,len,x,y,-stoneSize/2,stoneSize,etape,bx,by);
		}else if((etape==4)||(etape==7)) {     //g2
			pathBoard(nb,len,x,y,-stoneSize,0,etape,bx,by);
		}else  if((etape==6)||(etape==9)) {     //g1	
			pathBoard(nb,len,x,y,-stoneSize/2,-stoneSize,etape,bx,by);
		}else if((etape==11)||(etape==8)) {    //d1
			if(etape==11){
				pathBoard(nb,len-1,x,y,stoneSize/2,-stoneSize,etape,bx,by);
			}else{
				pathBoard(nb,len,x,y,stoneSize/2,-stoneSize,etape,bx,by);
			}



		}


		else {
			pathBoard(nb+1,x,y,0,bx,by);
		}


	}

	/***
	 * generate a board (position and number)
	 */
	void generateBoard(){

		pathBoard(0,width/2,0,0,0,-1);
	}


	private int[] getothers(int numplace,int[] current){


		//	System.out.println("0:"+current[0]+" 1:"+current[1]+" 2:"+current[2]);
		//System.out.println("3: "+current[3]+" 4:"+current[4]+" 5:"+current[5]);

		int total=current.length;


		for (int i=0;i<current.length;i++){
			if (current[i]==-1)total--;
		}

		//System.out.println(total+":"+current.length);
		boolean seek;
		//	int fin=numplace;
		for (int i=0;i<numplace;i++){//for each stone (candidate)
			int[] temp=getneighbors(i,false); //get neigbors
			//System.out.println("salut");

			for(int j=0;j<temp.length;j++){
				if (temp[j]==numplace ){ //if this stone is its neighbors
					seek=false;
					for(int k=0;k<current.length;k++){//check if i know him
						if(current[k]==i){
							seek=true;
							break;
						}

					}
					if(!seek)current[total++]=i;
				}
				if (current.length==total)break;
			}
			if (current.length==total)break;
		}
		//System.out.println("0:"+current[0]+" 1:"+current[1]+" 2:"+current[2]);
		//	System.out.println("3: "+current[3]+" 4:"+current[4]+" 5:"+current[5]);

		return current;
	}

	int[] getneighbors(int numplace,boolean all){
		int niveau;
		if(numplace>107)niveau=2;
		else if(numplace>83)niveau=3;
		else if(numplace>47)niveau=4;
		else niveau=5;



		int [] neigbors;

		if(niveau<=4){
			neigbors= new int[6];
			for (int i=0;i<neigbors.length;i++)neigbors[i]=-1;
			neigbors[0]=numplace+1;
			neigbors[1]=numplace-1;
			if(niveau==4){


				int shift1=numplace-48+places[numplace].branche+2;
				int shift2=numplace-48+places[numplace].branche-1;	
				if(shift1%8==0){
					neigbors[2]=numplace+2;

					//if(numplace==46)neigbors[2]=48;
				}
				if(shift2%8==0){

					neigbors[2]=numplace-2;
					if(numplace==49)neigbors[2]=83;

				}



				if((numplace-48)%6==0){
					//nothing to do
				}else{
					if(places[numplace].branche%2==0){

						neigbors[3]=numplace+35-places[numplace].branche;
						if(((numplace-47)%6!=0)&&((numplace-49)%6!=0)){
							neigbors[4]=neigbors[3]-1;
						}
						//neigbors[4]=neigbors[3]-1;
					}else{
						//System.out.println("salut");
						neigbors[3]=numplace+35-places[numplace].branche+1;
						if(((numplace-47)%6!=0)&&((numplace-49)%6!=0)){
							neigbors[4]=neigbors[3]+1;
						}


					}



					if((numplace-48)%3==0){ //corner
						neigbors[4]=neigbors[3]+1;
						neigbors[5]=neigbors[3]-1;

					}


				}
				if(numplace==83){
					neigbors[2]=48;
					neigbors[3]=49;
				}
				if(numplace==48)neigbors[1]=83;

				if(numplace==82)neigbors[4]=84;



				if(neigbors[2]==-1){
					neigbors[2]=neigbors[5];
					neigbors[5]=-1;
				}
				if(neigbors[2]==-1){
					neigbors[2]=neigbors[4];
					neigbors[4]=-1;
				}
				//	System.out.println("eheh0:"+neigbors[0]+" 1:"+neigbors[1]+" 2:"+neigbors[2]);
				//System.out.println("3: "+neigbors[3]+" 4:"+neigbors[4]+" 5:"+neigbors[5]);
			}else if(niveau==3){

				//	System.out.println(numplace-84);

				if((numplace-84)%4==0){
					//nothing to do
				}else{
					//neigbors[2]=numplace-82;
					neigbors[2]=numplace+23-places[numplace].branche;
					if(((numplace-84)%2==0)){
						neigbors[3]=neigbors[2]-1;
						neigbors[4]=neigbors[2]+1;
					}else{
						if (places[numplace].branche%2!=0){
							neigbors[2]++;		
							neigbors[3]=numplace+2;
						}else{
							neigbors[3]=numplace-2;	
						}



					}


				}
				if(numplace==84)neigbors[1]=107;
				if(numplace==85)neigbors[3]=107;
				if(numplace==107)neigbors[2]=84;
				if(numplace==107)neigbors[3]=85;
				if(numplace==106)neigbors[4]=108;

			}else{//niveau 2 and last



				//	System.out.println(numplace-107);
				if((numplace-107)%2==0){
					neigbors[2]=neigbors[0]-1;
					neigbors[2]=neigbors[0]+1;
					neigbors[3]=120;
				}
				if(numplace%2==1){
					neigbors[4]=neigbors[1]-1;
				}
				if(numplace==108)neigbors[1]=119;
				if(numplace==109)neigbors[4]=119;
				if (numplace==119){
					neigbors[2]=109;
					neigbors[3]=108;
				}
				if(numplace==120){
					neigbors[0]=117;

				}


			}






		}else{
			if(numplace%8==0){   //pique
				neigbors= new int[2];

				neigbors[0]=numplace+1;
				neigbors[1]=((numplace+47))%48;

			}else if(numplace%4==0){ 
				neigbors= new int[5];

				neigbors[0]=numplace+1;
				neigbors[1]=numplace-1;
				neigbors[2]=(numplace+48)-places[numplace].branche;
				neigbors[3]=neigbors[2]-1;
				neigbors[4]=neigbors[3]-1;
			}else{

				neigbors= new int[4];

				neigbors[0]=numplace+1;
				neigbors[1]=numplace-1;
				if ((numplace+1)%8==0){
					neigbors[2]=(numplace+2)%48;
					if(numplace==47){
						neigbors[3]=0;
					}else{
						neigbors[3]=(numplace+48)-places[numplace].branche;
					}
				}
				else if ((numplace-1)%8==0){
					neigbors[2]=(numplace+47)%49;
					if(numplace==1){
						neigbors[3]=47;
					}else{
						neigbors[3]=(numplace+48)-places[numplace].branche-1;
					}

				}
				else{
					neigbors[2]=(numplace+48)-places[numplace].branche;
					if(places[numplace].branche%2==0){
						neigbors[2]--;
						neigbors[3]=neigbors[2]-1;
					}else{
						neigbors[3]=neigbors[2]+1;
						if(neigbors[3]==84)neigbors[3]=48;
					}

				}

			}

		}


		if(!all||niveau==5)
			return neigbors;

		return getothers(numplace, neigbors);
	}

	/**
	 * @param  from (position) on the board
	 * @param  to (position) on the board
	 * @return the minimum  distance between these two position
	 */
	public   int min_distance_from(int from,int to){
		return Math.abs(places[from].bx-places[to].bx)+Math.abs(places[from].by-places[to].by);


	}


	/***
	 * Generate a graph to speed up the game
	 */
	public void generatePlacesGraph() {
		for(int i=0;i<121;i++){
			places[i].neigbors=getneighbors(i, true);
		}

	}

}
